﻿// Postgres.cpp: 实现文件
//

#include "pch.h"
#include "DataSynApp.h"
#include "afxdialogex.h"
#include "Postgres.h"
#include "DataSynAppDlg.h"
#include <iostream>
#include <libpq-fe.h>  // 包含libpq的头文件
#include <string>
#include <chrono>
#include <vector>
#include <iomanip>
#include <sstream>
// Postgres 对话框

IMPLEMENT_DYNAMIC(Postgres, CDialogEx)

Postgres::Postgres(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_TABPAGE3, pParent)
	, pgip(_T(""))
	, isok(FALSE)
	, pgport(_T(""))
	, pguser(_T(""))
	, pgpasswd(_T(""))
	, pgdbname(_T(""))
{

}

Postgres::~Postgres()
{
}

void Postgres::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT_sjk_ip, pgip);
	DDX_Check(pDX, IDC_CHECK1, isok);
	DDX_Text(pDX, IDC_EDIT_sjk_port, pgport);
	DDX_Text(pDX, IDC_EDIT_sjk_acc, pguser);
	DDX_Text(pDX, IDC_EDIT_skj_pwd, pgpasswd);
	DDX_Text(pDX, IDC_EDIT_sjk_name, pgdbname);
}


BEGIN_MESSAGE_MAP(Postgres, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_save, &Postgres::OnBnClickedButtonsave)
	ON_BN_CLICKED(IDC_BUTTON_test, &Postgres::OnBnClickedButtontest)
	ON_BN_CLICKED(IDC_BUTTON_test2, &Postgres::OnBnClickedButtontest2)
END_MESSAGE_MAP()


// Postgres 消息处理程序


void Postgres::OnBnClickedButtonsave()
{
	UpdateData(true);

	if (isok)
	{
		iniData[_T("POSTGRESOLCFG")][_T("isok")] = "1";
	}
	else
	{
		iniData[_T("POSTGRESOLCFG")][_T("isok")] = "0";
	}
	iniData[_T("POSTGRESOLCFG")][_T("pgip")]=pgip;
	iniData[_T("POSTGRESOLCFG")][_T("pgport")] = pgport;
	iniData[_T("POSTGRESOLCFG")][_T("pguser")] = pguser;
	iniData[_T("POSTGRESOLCFG")][_T("pgpasswd")] = pgpasswd;
	iniData[_T("POSTGRESOLCFG")][_T("pgdbname")] = pgdbname;
	WriteIniFile(appDlg->exePath, iniData);
}


BOOL Postgres::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	if (iniData[_T("POSTGRESOLCFG")][_T("isok")] == "1")
	{
		isok = true;
	}
	else
	{
		isok = false;
	}
	pgip = iniData[_T("POSTGRESOLCFG")][_T("pgip")];
	pgport = iniData[_T("POSTGRESOLCFG")][_T("pgport")];
	pguser = iniData[_T("POSTGRESOLCFG")][_T("pguser")];
	pgpasswd = iniData[_T("POSTGRESOLCFG")][_T("pgpasswd")];
	pgdbname = iniData[_T("POSTGRESOLCFG")][_T("pgdbname")];

	UpdateData(false);

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}


// 记录结构体
struct DataRecord {
	std::string realtime_id;
	double ts;
	std::string real_data_id;
	std::string well_id;
	std::string wellbore_id;
	std::string well_name;
	std::string welltime;
	double depth;
	double mudgl;
	double ttvol;
	double ttvolgl;
	std::string workinfo;
	double type;
	double gzl;
	double ymbhl;
	double ljymbhl;
	double qxzzh;
	double ljzs;
	double gjgzl;
	double ljgflcz;
	double ygfl;
	double sgfl;
	double ljygfl;
	double ljsgfl;
	double sgygcz;
	double bitdepth;
	std::string ymczfz;
	std::string ckgcqk;
	std::string jlr;
	std::string zbgb;
	std::vector<double> tvol; // 用于存储 tvol01 到 tvol24 的数据
	double tvol0;
	DataRecord() : tvol(24, 0.0) {} // 初始化 tvol 向量，大小为 24，初始值为 0.0
};

// 生成插入 SQL 语句
std::string generateInsertSQL(PGconn* conn, const DataRecord& record) {
	std::string realtime_id = PQescapeLiteral(conn, record.realtime_id.c_str(), record.realtime_id.length());
	std::string real_data_id = PQescapeLiteral(conn, record.real_data_id.c_str(), record.real_data_id.length());
	std::string well_id = PQescapeLiteral(conn, record.well_id.c_str(), record.well_id.length());
	std::string wellbore_id = PQescapeLiteral(conn, record.wellbore_id.c_str(), record.wellbore_id.length());
	std::string well_name = PQescapeLiteral(conn, record.well_name.c_str(), record.well_name.length());
	std::string welltime = PQescapeLiteral(conn, record.welltime.c_str(), record.welltime.length());
	std::string workinfo = PQescapeLiteral(conn, record.workinfo.c_str(), record.workinfo.length());
	std::string ymczfz = PQescapeLiteral(conn, record.ymczfz.c_str(), record.ymczfz.length());
	std::string ckgcqk = PQescapeLiteral(conn, record.ckgcqk.c_str(), record.ckgcqk.length());
	std::string jlr = PQescapeLiteral(conn, record.jlr.c_str(), record.jlr.length());
	std::string zbgb = PQescapeLiteral(conn, record.zbgb.c_str(), record.zbgb.length());

	std::string sql = "INSERT INTO drl_千库1 ("
		"realtime_id, ts, real_data_id, well_id, wellbore_id, well_name, "
		"welltime, depth, mudgl, ttvol, ttvolgl, workinfo, type, gzl, "
		"ymbhl, ljymbhl, qxzzh, ljzs, gjgzl, ljgflcz, ygfl, sgfl, "
		"ljygfl, ljsgfl, sgygcz, bitdepth, ymczfz, ckgcqk, jlr, zbgb, "
		"tvol01, tvol02, tvol03, tvol04, tvol05, tvol06, tvol07, "
		"tvol08, tvol09, tvol10, tvol11, tvol12, tvol13, tvol14, "
		"tvol15, tvol16, tvol17, tvol18, tvol19, tvol20, tvol21, "
		"tvol22, tvol23, tvol24, tvol) VALUES ("
		+ realtime_id + ", " +
		std::to_string(record.ts) + ", " +
		real_data_id + ", " +
		well_id + ", " +
		wellbore_id + ", " +
		well_name + ", " +
		welltime + ", " +
		std::to_string(record.depth) + ", " +
		std::to_string(record.mudgl) + ", " +
		std::to_string(record.ttvol) + ", " +
		std::to_string(record.ttvolgl) + ", " +
		workinfo + ", " +
		std::to_string(record.type) + ", " +
		std::to_string(record.gzl) + ", " +
		std::to_string(record.ymbhl) + ", " +
		std::to_string(record.ljymbhl) + ", " +
		std::to_string(record.qxzzh) + ", " +
		std::to_string(record.ljzs) + ", " +
		std::to_string(record.gjgzl) + ", " +
		std::to_string(record.ljgflcz) + ", " +
		std::to_string(record.ygfl) + ", " +
		std::to_string(record.sgfl) + ", " +
		std::to_string(record.ljygfl) + ", " +
		std::to_string(record.ljsgfl) + ", " +
		std::to_string(record.sgygcz) + ", " +
		std::to_string(record.bitdepth) + ", " +
		ymczfz + ", " +
		ckgcqk + ", " +
		jlr + ", " +
		zbgb + ", ";

	for (size_t i = 0; i < record.tvol.size(); ++i) {
		sql += std::to_string(record.tvol[i]);
		if (i < record.tvol.size() - 1) sql += ", ";
	}
	sql += ", ";
	sql += std::to_string(record.tvol0) ;
	sql += ");"; // 移除不必要的 tvol_size 插入

	return sql;
}

void batchInsertDataToDatabase(PGconn* conn, const std::vector<DataRecord>& records) {
	for (const auto& record : records) {
		std::string sql = generateInsertSQL(conn, record);
		std::cout << sql << std::endl;
		PGresult* res = PQexec(conn, sql.c_str());
		if (PQresultStatus(res) != PGRES_COMMAND_OK) {
			std::cerr << "Insert failed: " << PQerrorMessage(conn) << std::endl;
		}
		PQclear(res);
	}
}

std::string current_time_to_string() {
	auto now = std::chrono::system_clock::now();
	std::time_t now_time_t = std::chrono::system_clock::to_time_t(now);

	// 使用 localtime_s
	std::tm tm_ptr;
	localtime_s(&tm_ptr, &now_time_t); // 使用安全的 localtime_s

	std::ostringstream oss;
	oss << std::put_time(&tm_ptr, "%Y-%m-%d %H:%M:%S");
	return oss.str();
}
void Postgres::OnBnClickedButtontest()
{
	OnBnClickedButtonsave();
	std::string conninfo = "dbname=" + pgdbname + " "
		"user=" + pguser + " "
		"password=" + pgpasswd + " "
		"host=" + pgip + " "
		"port=" + pgport + " "
		"client_encoding=GBK"; // 根据需要设置编码

	// 建立与数据库的连接
	PGconn* conn = PQconnectdb(conninfo.c_str());

	// 检查连接是否成功
	if (PQstatus(conn) != CONNECTION_OK) {
		std::cerr << "连接数据库失败: " << PQerrorMessage(conn) << std::endl;
		isok = false;
		AfxMessageBox("连接数据库失败,自动取消数字化传输！");
	}
	else
	{
		std::cout << "成功连接到数据库!" << std::endl;
		AfxMessageBox("成功连接到数据库!!!");
		//isok = true;
	}


	UpdateData(false);


	PQfinish(conn);




	//	// 设置连接字符串
	//LPCSTR conninfo = "dbname=postgres "
	//	"user=postgres "
	//	"password=123456 "
	//	"host=127.0.0.1 "
	//	"port=5432 "
	//	"client_encoding=GBK"; // 使用 UTF-8 编码

	//// 建立与数据库的连接
	//PGconn* conn = PQconnectdb(conninfo);

	//// 检查连接是否成功
	//if (PQstatus(conn) != CONNECTION_OK) {
	//	std::cerr << "连接数据库失败: " << PQerrorMessage(conn) << std::endl;
	//	PQfinish(conn);
	//	return ; // 退出并返回错误
	//}

	//std::cout << "成功连接到数据库!" << std::endl;

	//// 示例要写入的数据
	//LPCSTR insertData = "INSERT INTO drl_千库1 (well_name) VALUES ('测试数据');";

	//// 执行插入操作
	//PGresult* res = PQexec(conn, insertData);

	//// 检查插入是否成功
	//if (PQresultStatus(res) != PGRES_COMMAND_OK) {
	//	std::cerr << "插入数据失败: " << PQerrorMessage(conn) << std::endl;
	//	PQclear(res);
	//	PQfinish(conn);
	//	return ; // 退出并返回错误
	//}

	//std::cout << "数据插入成功!" << std::endl;

	//// 清理资源
	//PQclear(res);
	//PQfinish(conn);


 

}



void Postgres::OnBnClickedButtontest2()
{
	// 设置连接字符串
	LPCSTR conninfo = "dbname=postgres "
		"user=postgres "
		"password=123456 "
		"host=127.0.0.1 "
		"port=5432 "
		"client_encoding=GBK"; // 使用 GBK 编码

	// 建立与数据库的连接
	PGconn* conn = PQconnectdb(conninfo);
	if (PQstatus(conn) != CONNECTION_OK) {
		std::cerr << "Connection to database failed: " << PQerrorMessage(conn) << std::endl;
		PQfinish(conn);
	}

	std::vector<DataRecord> records;

	// 示例数据生成
	for (int i = 0; i < 100; ++i) { // 生成 10 条记录
		DataRecord record;
		record.realtime_id = current_time_to_string(); // 动态获取当前时间
		record.ts = 100.5 + i;
		record.real_data_id = "2024-09-25";
		record.well_id = "WELL_00" + std::to_string(i + 1);
		record.wellbore_id = "WELLBORE_00" + std::to_string(i + 1);
		record.well_name = "测试井" + std::to_string(i + 1);
		record.welltime = "2024-09-25";
		record.depth = 1500.0 + (i * 10);
		record.mudgl = 1.0 + (i * 0.1);
		record.ttvol = 2.0 + (i * 0.2);
		record.ttvolgl = 3.0 + (i * 0.3);
		record.workinfo = "工作信息示例";
		record.type = 1.0 + (i * 0.1);
		record.gzl = 2.0 + (i * 0.2);
		record.ymbhl = 3.0 + (i * 0.3);
		record.ljymbhl = 4.0 + (i * 0.4);
		record.qxzzh = 5.0 + (i * 0.5);
		record.ljzs = 6.0 + (i * 0.6);
		record.gjgzl = 7.0 + (i * 0.7);
		record.ljgflcz = 8.0 + (i * 0.8);
		record.ygfl = 9.0 + (i * 0.9);
		record.sgfl = 10.0 + (i * 1.0);
		record.ljygfl = 11.0 + (i * 1.1);
		record.ljsgfl = 12.0 + (i * 1.2);
		record.sgygcz = 13.0 + (i * 1.3);
		record.bitdepth = 14.0 + (i * 1.4);
		record.ymczfz = "压密层辅助";
		record.ckgcqk = "存储工程情况";
		record.jlr = "记录人示例";
		record.zbgb = "指标规定示例";
		for (size_t j = 0; j < record.tvol.size(); ++j) {
			record.tvol[j] = 1.0 + (i * 0.1 + j * 0.01); // 填充 tvol 数据
		}
		record.tvol0 = 1.0+ i * 0.3;
		records.push_back(record);
	}

	// 批量插入数据
	batchInsertDataToDatabase(conn, records);

	// 关闭数据库连接
	PQfinish(conn);
}
